package com.gitee.faster.webdav.common.structure;

import cn.hutool.core.date.BetweenFormatter;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.unit.DataSizeUtil;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.RuntimeUtil;
import cn.hutool.system.SystemUtil;
import cn.hutool.system.oshi.OshiUtil;
import com.gitee.faster.webdav.FasterWebDavApplication;
import com.gitee.faster.webdav.common.constant.Constants;
import com.gitee.faster.webdav.kernel.Configuration;
import lombok.Data;
import lombok.experimental.Accessors;
import oshi.hardware.GlobalMemory;

import java.io.File;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

/**
 * @author hongda.li
 */
@Data
@Accessors(chain = true)
public class SystemSnapshot {
    /**
     * 系统版本
     */
    private String version;

    /**
     * 运行时长
     */
    private String runtime;

    /**
     * 访问地址
     */
    private String homeUrl;

    /**
     * 用户目录
     */
    private String userHome;

    /**
     * 操作系统
     */
    private String osName;

    /**
     * 系统架构
     */
    private String osArch;

    /**
     * 磁盘总容量
     */
    private String diskTotal;

    /**
     * 磁盘可用容量
     */
    private String diskFree;

    /**
     * 内存总容量
     */
    private String memoryTotal;

    /**
     * 内存可用容量
     */
    private String memoryFree;

    /**
     * CPU 核心数量
     */
    private String cpuCoreNum;

    /**
     * 系统配置信息
     */
    private Configuration config;

    /**
     * 日志相关信息
     */
    private List<LogInfo> logInfoList;

    @Data
    @Accessors(chain = true)
    public static final class LogInfo {
        /**
         * 日志时间
         */
        private String logTime;

        /**
         * 日志路径
         */
        private String logPath;

        public static LogInfo byFile(File file) {
            return new LogInfo()
                    .setLogPath(file.getAbsolutePath())
                    .setLogTime(CharSequenceUtil.removeSuffix(file.getName(), Constants.LOG_SUFFIX));
        }
    }

    /**
     * 创建一个系统快照
     *
     * @return 系统快照
     */
    public static SystemSnapshot snapshot() {
        SystemSnapshot snapshot = new SystemSnapshot();

        snapshot.version = Constants.VERSION;
        snapshot.runtime = DateUtil.formatBetween(System.currentTimeMillis() - FasterWebDavApplication.getTimestamp(), BetweenFormatter.Level.SECOND);
        snapshot.cpuCoreNum = Integer.toString(RuntimeUtil.getProcessorCount());

        Configuration configuration = Configuration.getInstance();
        snapshot.homeUrl = configuration.httpPathBuilder().build();
        snapshot.config = configuration;
        snapshot.userHome = FileUtil.getUserHomePath();
        snapshot.osName = SystemUtil.getOsInfo().getName();
        snapshot.osArch = SystemUtil.getOsInfo().getArch();

        GlobalMemory memory = OshiUtil.getMemory();
        snapshot.memoryTotal = DataSizeUtil.format(memory.getTotal());
        snapshot.memoryFree = DataSizeUtil.format(memory.getAvailable());

        OshiUtil.getOs()
                .getFileSystem()
                .getFileStores()
                .stream()
                .filter(store -> FileUtil.isSub(new File(store.getMount()), new File(configuration.getStoragePath())))
                .findFirst()
                .ifPresent(store -> {
                    snapshot.diskTotal = DataSizeUtil.format(store.getTotalSpace());
                    snapshot.diskFree = DataSizeUtil.format(store.getUsableSpace());
                });

        snapshot.logInfoList = Arrays.stream(FileUtil.ls(configuration.getLoggerPath()))
                .map(LogInfo::byFile)
                .sorted(Comparator.comparing(LogInfo::getLogTime).reversed())
                .limit(10L)
                .toList();

        return snapshot;
    }
}
